#pragma once
#include "requestor.hpp"
#include <unordered_set>

namespace bitrpc{
    namespace client{
        //客户端主题管理类
        // 负责客户端与服务端之间的主题操作通信：
        // 1. 提供主题的创建、删除、订阅、取消订阅和发布功能
        // 2. 管理主题订阅的回调函数
        // 3. 处理服务端推送的主题消息
        
        class TopicManager{
            public:
            using SubCallback = std::function<void(const std::string &key, const std::string &msg)>;
            using ptr = std::shared_ptr<TopicManager>;

            //requestor请求发送器
            TopicManager(const Requestor::ptr &requestor):_requestor(requestor){}
            
            //创建主题
            bool create(const BaseConnection::ptr &conn, const std::string &key){
                return commonRequest(conn, key, TopicOptype::TOPIC_CREATE);
            }

            //删除主题
            bool remove(const BaseConnection::ptr &conn, const std::string &key){
                return  commonRequest(conn, key, TopicOptype::TOPIC_REMOVE);
            }

            //订阅主题
            bool subscribe(const BaseConnection::ptr &conn, const std::string &key, const SubCallback &cb){
                addSubscribe(key, cb);
                bool ret = commonRequest(con, key, TopicOptype::TOPIC_SUBSCRIBE));
                if(ret == false){
                    deSubscribe(key);
                    return false;
                }
            }

            //取消订阅
            bool cancel(const BaseConnection::Ptr &conn, const std::string &key){
                deSubscribe(key);
                return commonRequest(conn, key, TopicOptype::TOPIC_CANCEL);
            }
            
            //发布消息
            bool publish(const BaseConnection::ptr &conn, const std::string &key, const std::string &msg) {
                    return commonRequest(conn, key, TopicOptype::TOPIC_PUBLISH, msg);
                }

            //处理服务端推送的主题消息
            // 1. 验证消息类型是否为发布操作
            // 2. 提取主题名称和消息内容
            //  3. 查找并调用对应的回调函数
            void onPublish(const BaseConnection::ptr &conn, const TopicRequest::ptr &msg) {
                    // 验证消息类型
                    auto type = msg->optype();
                    if (type != TopicOptype::TOPIC_PUBLISH) {
                        ELOG("收到了错误类型的主题操作！");
                        return;
                    }
                    
                    // 提取主题信息
                    std::string topic_key = msg->topicKey();
                    std::string topic_msg = msg->topicMsg();
                    
                    // 查找并调用回调函数
                    auto callback = getSubscribe(topic_key);
                    if (!callback) {
                        ELOG("收到了 %s 主题消息，但是该消息无主题处理回调！", topic_key.c_str());
                        return;
                    }
                    return callback(topic_key, topic_msg);
                }
            private:
            //添加主题订阅回调
            void addSubscribe(const std::string &key, const SubCallback &cb){
                std::unique_lock<std::mutex> (_mutex);
                _topic_callbacks.insert(std::make_pair(key, cb));
            }
            //删除主题订阅回调
            void deSubscribe(const std::string &key){
                std::unique_lock<std::mutex> (_mutex);
                _topic_callbacks.erase(key);
            }
            //获得主题订阅回调
            const SubCallback getSubscribe(const std::string &key){
                std::unique_lock<std::mutex> lock(_mutex);
                auto it = _topic_callbacks.find(key);
                if(it == _topic_callbacks.end()){
                    return SubCallback();
                }
                return it->second;
            }
            //通用请求发送方法
            bool commonRequest(const BaseConnection::ptr &conn, const std::string &key,
                TopicOptype type, const std::string &msg = ""){
                    //构造请求对象
                    auto msg_req = MessageFactory::create<TopicRequest>();
                    msg_req->setId(UUID::uuid);
                    msg_req->setMType(MType::REQ_TOPIC);
                    msg_req->setOptype(type);
                    msg_req->setTopicKey(key);
                    if (type == TopicOptype::TOPIC_PUBLISH) {
                        msg_req->setTopicMsg(msg);
                    }

                    //发送请求并等待响应
                    BaseMessage::ptr msg_rsp;
                    bool ret = _requestor->send(conn, msg_req, msg_rsp);
                    if(ret == false){
                        ELOG("主题操作请求失败!");
                        return false;
                    }

                    //解析响应
                    auto topic_rsp_msg = std::dynamic_pointer_cast<TopicResponse>(msg_rsp);
                    if (!topic_rsp_msg) {
                        ELOG("主题操作响应，向下类型转换失败！");
                        return false;
                    }
                    if (topic_rsp_msg->rcode() != RCode::RCODE_OK) {
                        ELOG("主题操作请求出错：%s", errReason(topic_rsp_msg->rcode()));
                        return false;
                    }
                    return true;
                    }
                }
            private:
            std::mutex _mutex;                                               // 保护回调映射的互斥锁
            std::unordered_map<std::string, SubCallback> _topic_callbacks;  // 主题名称到回调函数的映射
            Requestor::ptr _requestor;                                      // 请求发送器
        }
    }
}